import axios from 'axios';
import Keycloak from 'keycloak-js';
import { saveAs } from 'file-saver';

async function initKeycloak() {
  const keycloak = new Keycloak();
  console.log('set keycloak');
  await keycloak.init({onLoad: 'login-required'});
  return keycloak.token;
}

const { v4: uuidv4 } = require('uuid');
const XLSX = require("xlsx");
const ExcelJS = require('exceljs');

$(document).ready(async function () {
  var str = window.location.search;
  var rule_id = str.substring(4, str.length);
  var decision_id = rule_id.split(':')[0];
  console.log(decision_id);
  var token = await initKeycloak();
  axios.create({withCredentials: true}).get(
    'http://localhost/camunda/engine-rest/decision-definition/'+rule_id+'/xml', 
    {headers: {'Content-Type':'application/json', 'Authorization':'Bearer '+token}}
    ).then(
      res=>{
        //console.log(res.data.dmnXml);
        let parser = new DOMParser();
        let xmlDoc = parser.parseFromString(res.data.dmnXml,"text/xml");
        let decisions = xmlDoc.getElementsByTagName("decision");
        var decision = null;
        for (var i=0;i<decisions.length;i++) {
          for (var j=0;j<decisions[i].attributes.length;j++) {
            if (decisions[i].attributes[j].name=='id' && decisions[i].attributes[j].value==decision_id) {
              decision = decisions[i];
              break;
            }
          }
          if (decision!=null) {
            break;
          }
        }

        let input_arr = decision.getElementsByTagName("input");
        console.log(input_arr);
        let output_arr = decision.getElementsByTagName("output");
        let input_expression_arr = decision.getElementsByTagName("inputExpression");
        let output_str = [];
        let input_str = [];
        let input_values = [];
        let input_id = [];
        let json_data = [];
        let column_names = [];
        let input_type = [];
        let output_type = [];
        let output_id = [];
        let output_values = [];
        for (var i=0;i<input_arr.length;i++) {
          let item = input_arr.item(i);
          for (var j=0;j<item.attributes.length;j++) {
            if (item.attributes[j].name=='label') {
              input_str.push(item.attributes[j].value);
            }
            if (item.attributes[j].name=='id') {
              input_id.push(item.attributes[j].value);
            }
          }
          let childNodes = item.childNodes;
          let inputValue = [];
          for (var j=0;j<childNodes.length;j++) {
            if (childNodes[j].nodeName=="inputValues") {
              inputValue = childNodes[j].childNodes[1].firstChild.nodeValue.split(',');
              for (var k=0;k<inputValue.length;k++) {
                if (inputValue[k][0]=='"' && inputValue[k][inputValue[k].length-1]=='"') {
                  inputValue[k] = inputValue[k].substring(1,inputValue[k].length-1);
                }
              }
              break;
            }
          }
          input_values.push(inputValue);
        }
        for (var i=0;i<input_expression_arr.length;i++) {
          let item = input_expression_arr.item(i);
          for (var j=0;j<item.attributes.length;j++) {
            if (item.attributes[j].name=='typeRef') {
              input_type.push(item.attributes[j].value);
            }
          }
        }
        for (var i=0;i<output_arr.length;i++) {
          let item = output_arr.item(i);
          for (var j=0;j<item.attributes.length;j++) {
            if (item.attributes[j].name=='label') {
              output_str.push(item.attributes[j].value);
            }
            if (item.attributes[j].name=='id') {
              output_id.push(item.attributes[j].value);
            }
            if (item.attributes[j].name=='typeRef') {
              output_type.push(item.attributes[j].value);
            }
          }

          let childNodes = item.childNodes;
          let outputValue = [];
          for (var j=0;j<childNodes.length;j++) {
            if (childNodes[j].nodeName=="outputValues") {
              outputValue = childNodes[j].childNodes[1].firstChild.nodeValue.split(',');
              for (var k=0;k<outputValue.length;k++) {
                if (outputValue[k][0]=='"' && outputValue[k][outputValue[k].length-1]=='"') {
                  outputValue[k] = outputValue[k].substring(1,outputValue[k].length-1);
                }
              }
              break;
            }
          }
          output_values.push(outputValue);
        }
        let tablestr = '<thead><tr>';
        for (var i=0;i<input_str.length;i++) {
          tablestr += '<th>'+input_str[i]+'</th>';
          column_names.push(input_str[i]);
        }
        for (var i=0;i<output_str.length;i++) {
          tablestr += '<th>'+output_str[i]+'</th>';
          column_names.push(output_str[i]);
        }
        tablestr += '</tr></thead><tbody></tbody>';
        $('#dataTable').append(tablestr);
        //let table = $('#dataTable').DataTable();
        //table.columns.adjust().draw();
        let rules_arr = decision.getElementsByTagName("rule");
        let rules_str = [];
        let rows_arr = [];
        for (i=0;i<rules_arr.length;i++) {
          let ruleChild = rules_arr.item(i).childNodes;
          let ruleItem = [];
          let rowItem = {};
          let column_id = 0;
          for (j=0;j<ruleChild.length;j++) {
            if (ruleChild[j].nodeName=="inputEntry" || ruleChild[j].nodeName=="outputEntry") {
              //console.log(ruleChild[j].childNodes[1].firstChild);
              if (ruleChild[j].childNodes[1].firstChild) {
                if (ruleChild[j].childNodes[1].firstChild.nodeValue) {
                  let value = ruleChild[j].childNodes[1].firstChild.nodeValue;
                  //去除双引号
                  if (value.indexOf('"')==0 && value.indexOf('"', value.length-1)==value.length-1) {
                    value = value.substring(1, value.length-1);
                  }
                  ruleItem.push(value);
                  rowItem[column_names[column_id]] = value;
                } else {
                  console.log(ruleChild[j].childNodes[1]);
                  ruleItem.push("");
                  rowItem[column_names[column_id]] = "";
                }
              } else {
                ruleItem.push("");
                rowItem[column_names[column_id]] = "";
              }
              column_id += 1;
            }
          }
          rules_str.push(ruleItem);
          rows_arr.push(rowItem);
        }
        $('#dataTable').DataTable({
          data: rules_str,
          scrollX: true,
          autoWidth: false
        }).columns.adjust();
        /*
        const worksheet = XLSX.utils.json_to_sheet(rows_arr);
        const workbook = XLSX.utils.book_new();
        var sheetname = rule_id.split(':')[0];
        var sheetname = sheetname.length>31?sheetname.substring(0,30):sheetname;
        XLSX.utils.book_append_sheet(workbook, worksheet, sheetname);
        $('#js-download-dmn-xls').click(function(e) {
          XLSX.writeFile(workbook, sheetname+".xlsx");
        });
        */
        const workbook = new ExcelJS.Workbook();
        var sheetname = rule_id.split(':')[0];
        var sheetname = sheetname.length>31?sheetname.substring(0,30):sheetname;
        const sheet = workbook.addWorksheet(sheetname);
        var columns = [];
        for (var i=0;i<input_id.length;i++) {
          columns.push({
            header: input_str[i],
            key: input_id[i],
            width: 30
          });
        }
        for (var i=0;i<output_id.length;i++) {
          columns.push({
            header: output_str[i],
            key: output_id[i],
            width: 30
          });
        }
        sheet.columns = columns;
        for (var i=0;i<rows_arr.length;i++) {
          sheet.addRow(rules_str[i]);
        }
        console.log("log start");
        console.log(input_values);
        console.log(output_values);
        //console.log('"'+input_values[i].join(',')+'"');
        for (var i=0;i<input_values.length;i++) {
          if (input_values[i].length>0) {
            /*
            console.log('"'+input_values[i].join(',')+'"');
            sheet.getColumn(i+1).eachCell({ includeEmpty: true }, function(cell, rowNumber) {
              if (rowNumber>1) {
                cell.dataValidation = {
                  type: 'list',
                  allowBlank: true,
                  formulae: ['"'+input_values[i].join(',')+'"']
                };
              }
            });
            */
            var a = Math.floor(i/26);
            var columnName = '';
            if (a==0) {
              columnName = String.fromCharCode(i%26+65);
            }
            else if (a==1) {
              columnName = String.fromCharCode(65)+String.fromCharCode(i%26+65);
            }
            else {
              columnName = String.fromCharCode(a-1+65)+String.fromCharCode(i%26+65);
            }
            sheet.dataValidations.add(columnName+"2:"+columnName+"9999",{
              type: 'list',
              allowBlank: true,
              formulae: ['"'+input_values[i].join(',')+'"']
            });
          }
        }
        for (var i=0;i<output_values.length;i++) {
          if (output_values[i].length>0) {
            console.log("input_values.length");
            console.log(input_values.length);
            console.log(i);
            var a = Math.floor((i+input_values.length)/26);
            var columnName = '';
            if (a==0) {
              columnName = String.fromCharCode((i+input_values.length)%26+65);
            }
            else if (a==1) {
              columnName = String.fromCharCode(65)+String.fromCharCode((i+input_values.length)%26+65);
            }
            else {
              columnName = String.fromCharCode(a-1+65)+String.fromCharCode((i+input_values.length)%26+65);
            }
            sheet.dataValidations.add(columnName+"2:"+columnName+"9999",{
              type: 'list',
              allowBlank: true,
              formulae: ['"'+output_values[i].join(',')+'"']
            });
          }
        }
        
        
        /*
        workbook.xlsx.writeBuffer({base64: true})
          .then(function (xls64) {
            var data = new Blob([xls64], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});
            var url = URL.createObjectURL(data);
            $('#js-download-dmn-xls').href = url;
            $('#js-download-dmn-xls').download = sheetname+".xlsx";
            //$('#js-download-dmn-xls').click();
          });
        */
       /*
        sheet.commit();
        workbook.commit();
        $('#js-download-dmn-xls').click(function(e) {
          console.log("ffffffffffffffff");
          console.log(workbook);
          workbook.xlsx.writeBuffer({base64: true})
          .then(function (xls64) {
            console.log("aaaaaaaaaaaaaaaa");
            console.log(xls64);
            var data = new Blob([xls64], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});
            var url = URL.createObjectURL(data);
            console.log("GGGGGGGGGGGGGGGGGGGGG");
            console.log(url);
            $('#js-download-dmn-xls').href = url;
            $('#js-download-dmn-xls').download = sheetname+".xlsx";
            //$('#js-download-dmn-xls').click();
          });
        });
        */
        $('#js-download-dmn-xls').click(async function(e) {
          var xls64 = await workbook.xlsx.writeBuffer({ base64: true });
          saveAs(
            new Blob([xls64], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }),
            sheetname+'.xlsx'
          )
        });

        $('#js-deploy-dmn-xls').click(async function(e) {
          const [rFile] = await window.showOpenFilePicker({
            types: [{
              description: 'Spreadsheets',
              accept: { 'application/vnd.ms-excel': ['.xlsx', '.xls', '.xlsb', /*...*/] }
            }],
            excludeAcceptAllOption: true,
            multiple: false
          });
          const ab = await (await rFile.getFile()).arrayBuffer();
          const wb = XLSX.read(ab);
          const sheet = wb['Sheets'][wb['SheetNames'][0]];
          const cellkeys = Object.keys(sheet);
          let index = 1+input_arr.length+output_arr.length; 
          const rows = Math.floor((cellkeys.length-1)/(input_arr.length+output_arr.length))-1;
          let rule_nodes = [];
          for (var i=0;i<rows;i++) {
            let rulestr = '\n      <rule id="DecisionRule_' + uuidv4().split('-')[4].substring(0,7) + '">\n';
            for (var j=0;j<input_arr.length;j++) {
              let value = sheet[cellkeys[index]]['v'];
              if (input_type[j]=='string') {
                value = '"' + value + '"';
              }
              rulestr += '        <inputEntry id="UnaryTests_' + uuidv4().split('-')[4].substring(0,7) + '">\n';
              rulestr += '          <text>' + value + '</text>\n        </inputEntry>\n';
              index++;
            }
            for (var j=0;j<output_arr.length;j++) {
              let value = sheet[cellkeys[index]]['v'];
              if (output_type[j]=='string') {
                value = '"' + value + '"';
              }
              rulestr += '        <outputEntry id="LiteralExpression_' + uuidv4().split('-')[4].substring(0,7) + '">\n';
              rulestr += '          <text>' + value + '</text>\n        </outputEntry>\n';
              index++;
            }
            rulestr += '      </rule>\n';
            let rule_element = parser.parseFromString(rulestr,"text/xml").firstChild;
            rule_nodes.push(rule_element);
          }
          let rule_elements = decision.getElementsByTagName("rule");
          const rules_length = rule_elements.length;
          let decision_table_element = decision.getElementsByTagName("decisionTable")[0];
          for (var i=0;i<rules_length;i++) {
            decision_table_element.removeChild(rule_elements[0]);
          }
          for (var i=0;i<rule_nodes.length;i++) {
            decision_table_element.appendChild(rule_nodes[i]);
          }
          let xmlserializer = new XMLSerializer();
          let newXML = xmlserializer.serializeToString(xmlDoc);
          newXML = newXML.replace(/xmlns=\"\"/g, '');
          const file = new File([newXML], "diagram.dmn", {type: "text/plain"});
          const data = new FormData();
          data.append("deployment-name", rule_id);
          data.append("data", file);
          axios.create({withCredentials: true}).post(
            'http://localhost/camunda/engine-rest/deployment/create', 
            data, 
            {headers: {'Content-Type':'multipart/form-data', 'Authorization':'Bearer '+token}}
            ).then(
              res=>{
                if (res.status==200) {
                  alert("部署成功，点击链接查看:"+res.data.links[0].href);
                }
                //location.reload();
              }
            )
        });
      }
    )
});
  